#include "StaticMesh.h"
#include "2DTexture.h"
#include "RenderableVertexs.h"

#define USHORT_FROM_DATA *((uint16*)l_data)
#define READ_USHORT l_file.seekg(l_fileCursor); l_file.read(l_data,2);l_fileCursor+=2;


CStaticMesh::~CStaticMesh()
{

}


bool CStaticMesh::Load(const std::string &FileName)
{
	fstream l_file;
	l_file.open(FileName, ios::in |ios::binary);

	if(l_file==NULL) assert(ELL_ERROR);

	unsigned int l_fileCursor=0;

	char l_data[4]; //buffer para la extraccion de datos
	uint16 l_matQty; //varieble local para la cantidad de materiales
	uint16 l_bytesPerVertex=0;

	//Variables por cada material
	uint16				l_VertexType=0;	//variable local para el vertex type
	uint16				l_textQty=0;	//Cantidad de texturas
	uint16				l_charQty=0;	//Cantidad de caracteres en el nombre del archivo
	char*				l_cTextName=NULL;	//Nombre de la textura
	CTexture*			l_texture;		//Objeto textura para meter en el vector
	vector<CTexture*>	l_textVector;	//Vector para el vector de texturas
	uint16				l_vtxQty=0;		//Cantidad de vertices
	char*				l_vtxArray=NULL;
	CRenderableVertexs*	l_RenderableVertex=NULL;
	uint16				l_idxQty=0; 
	char*				l_idxArray=NULL;

	l_texture= new C2DTexture();
	

	READ_USHORT;
	//Verifico el header
	if(!(l_data[0]==0x55 && l_data[1]==0xff)) return false;
	

	//Cantidad de materiales
	READ_USHORT;
	l_matQty=USHORT_FROM_DATA;
	

	//info de materiales
	for(uint16 i=0;i<l_matQty;++i)
	{


		READ_USHORT;
		l_VertexType=USHORT_FROM_DATA;//VertexType
		l_bytesPerVertex=m_GetBytesPerVertex(l_VertexType);


		READ_USHORT;
		l_textQty=USHORT_FROM_DATA;//Cantidad de texturas del material
		
		

		for(uint16 j=0;j<l_textQty;++j)
		{	
			
			
			READ_USHORT;
			l_charQty=USHORT_FROM_DATA;//Cantidad de caracteres del nombre de archivo de textura
			l_cTextName=new char[l_charQty];
			l_file.seekg(l_fileCursor);
			l_file.read(l_cTextName,l_charQty);
			l_fileCursor+=l_charQty;

			l_charQty+=16;				//el 16 corresponde al "./data/textures/"
			string l_sTextName(l_cTextName,l_charQty);

			l_texture->Load(l_sTextName);
			
			l_textVector.push_back(l_texture);
						
		}

		m_Textures.push_back(l_textVector);
		l_textVector.clear();

		READ_USHORT;
		l_vtxQty=USHORT_FROM_DATA;
		l_vtxArray= new char [l_vtxQty*l_bytesPerVertex];
		l_file.seekg(l_fileCursor);
		l_file.read(l_vtxArray,l_vtxQty*l_bytesPerVertex);
		l_fileCursor+=l_vtxQty*l_bytesPerVertex;

		READ_USHORT;
		l_idxQty=USHORT_FROM_DATA;
		l_idxArray= new char[l_idxQty*2];
		l_file.seekg(l_fileCursor);
		l_file.read(l_idxArray,l_idxQty*2);
		l_fileCursor+=l_idxQty*2;

		switch(l_VertexType)
		{
		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_DIFFUSE):
			l_RenderableVertex= new CIndexedVertexs<TCOLORED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_TEXTURE1):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;
		
		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_DIFFUSE|VERTEX_TYPE_TEXTURE1):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_COLORED_TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;
		
		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_TEXTURE1|VERTEX_TYPE_TEXTURE2):
			l_RenderableVertex= new CIndexedVertexs<T2TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;
			
		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_DIFFUSE|VERTEX_TYPE_TEXTURE1|VERTEX_TYPE_TEXTURE2):
			l_RenderableVertex= new CIndexedVertexs<TCOLORED_2TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_DIFFUSE|VERTEX_TYPE_TEXTURE1|VERTEX_TYPE_TEXTURE2|VERTEX_TYPE_TANGENT|VERTEX_TYPE_BINORMAL):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_COLORED_TANGENT_BINORMAL_2TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_DIFFUSE):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_COLORED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);			
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_DIFFUSE|VERTEX_TYPE_TEXTURE1):
			l_RenderableVertex= new CIndexedVertexs<TCOLORED_TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_DIFFUSE|VERTEX_TYPE_TEXTURE1|VERTEX_TYPE_TEXTURE2):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_COLORED_2TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_TEXTURE1):
			l_RenderableVertex= new CIndexedVertexs<TTEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_TEXTURE1|VERTEX_TYPE_TEXTURE2):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_2TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;

		case(VERTEX_TYPE_GEOMETRY|VERTEX_TYPE_NORMAL|VERTEX_TYPE_DIFFUSE|VERTEX_TYPE_TANGENT|VERTEX_TYPE_BINORMAL|VERTEX_TYPE_TEXTURE1):
			l_RenderableVertex= new CIndexedVertexs<TNORMAL_COLORED_TANGENT_BINORMAL_TEXTURED_VERTEX>(CORE->GetGraphicsManager(),l_vtxArray,l_idxArray,l_vtxQty,l_idxQty);
			break;
		}


		
		delete [] l_vtxArray;
		delete [] l_idxArray;
		delete [] l_cTextName;
		delete l_RenderableVertex;
 		

	}

	delete l_texture;
	READ_USHORT;
	if(!(l_data[0]==0xff && l_data[1]==0x55)) return true;
	else return false;
	
}

uint16 m_GetBytesPerVertex(uint16 _vtxType)
{
	uint16 l_bytesPerVertex=0;

	if(_vtxType&&VERTEX_TYPE_GEOMETRY)	l_bytesPerVertex+=12;
	if(_vtxType&&VERTEX_TYPE_NORMAL)	l_bytesPerVertex+=12;
    if(_vtxType&&VERTEX_TYPE_TANGENT)	l_bytesPerVertex+=4;
	if(_vtxType&&VERTEX_TYPE_BINORMAL)	l_bytesPerVertex+=4;
	if(_vtxType&&VERTEX_TYPE_TEXTURE1)	l_bytesPerVertex+=8;
	if(_vtxType&&VERTEX_TYPE_TEXTURE2)	l_bytesPerVertex+=8;
	if(_vtxType&&VERTEX_TYPE_DIFFUSE)	l_bytesPerVertex+=4;

	return l_bytesPerVertex;

}












